package com.wang.web3;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.wang.web3.contracts.KittyBase;
import com.wang.web3.contracts.RandomBox;

import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.Web3jFactory;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.RemoteCall;
import org.web3j.protocol.core.methods.response.EthAccounts;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.core.methods.response.Web3ClientVersion;
import org.web3j.protocol.http.HttpService;
import org.web3j.tuples.generated.Tuple2;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.concurrent.ExecutionException;

import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;


public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    //grass two luxury cecrtain ball seed adjust horse quote scare
    Web3j web3;
    //设置需要的矿工费
     BigInteger GAS_PRICE = BigInteger.valueOf(22_000_000_000L);
     BigInteger GAS_LIMIT = BigInteger.valueOf(4_300_000);
    //转账人账户地址
    String ownAddress = "0x0bD386682c1cA777Ec52Cff00A9b1D770c707337";
    //被转人账户地址
    String toAddress = "0x1da044b9d9f255eD32c36b90060cdb92746a269e";

    RandomBox randomBox,randomBox1;
    KittyBase kittyBase;
//    KittyAccessControl kittyAccessControl,kittyAccessControl1;
    Credentials credentials;

    TextView textview,mToAddress,mFormAddress,mSerchAddress,mSerachBlance,mtvTestDeploy;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         textview = findViewById(R.id.textview);
        Button mBTestTrasation = findViewById(R.id.mBTestTrasation);
        Button mBTestBlance = findViewById(R.id.mBTestBlance);
         mToAddress = findViewById(R.id.tvToAddress);
         mFormAddress = findViewById(R.id.tvFromAddress);
        mSerchAddress = findViewById(R.id.mSerchAddress);
        mSerachBlance = findViewById(R.id.mSerachBlance);
        mtvTestDeploy = findViewById(R.id.mtvTestDeploy);
        mBTestTrasation.setOnClickListener(this);
        mBTestBlance.setOnClickListener(this);

        init();
        initConecation();


        try {

            EthAccounts ss = web3.ethAccounts().sendAsync().get();
            List<String> list = ss.getAccounts();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < list.size(); i++) {
                sb.append(list.get(i));
            }

//            String filePath = Environment.getExternalStorageDirectory().toString() + "";
           /* String filePath = Environment.getExternalStorageDirectory().getAbsolutePath().toString() + "";
            String fileName = WalletUtils.generateNewWalletFile("password",new File(filePath),false);
            Credentials credentials = WalletUtils.loadCredentials("password", filePath+"/"+fileName);*/
//                "/storage/emulated/0/UTC--2018-04-02T02-12-54.242--919501d3e121f38f983281d75c9cbf53bc20442e.json"
//                        "0x919501d3e121f38f983281d75c9cbf53bc20442e"
            //            Credentials credentials = WalletUtils.loadCredentials("c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3","0x627306090abaB3A6e1400e9345bC60c78a8BEf57");
//            credentials.getAddress();
//            String myAddress = credentials.getAddress();
//            textview.setText(sb.toString());
            // 加载钱包
//            Credentials credentials = WalletUtils.loadCredentials("c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", "0x627306090abaB3A6e1400e9345bC60c78a8BEf57");
            // 加载合约
//            Transfer keySCode = Transfer.load(SMART_CONTRACT_ADDRESS, web3, credentials, BigInteger.valueOf(27000000000L), BigInteger.valueOf(250000));
//            KittyAccessControl_sol_KittyAccessControl keySCode = KittyAccessControl_sol_KittyAccessControl.load("contractAddress", web3, credentials, BigInteger.valueOf(27000000000L), BigInteger.valueOf(250000));
//            RemoteCall<KittyAccessControl_sol_KittyAccessControl> keySCode = KittyAccessControl_sol_KittyAccessControl.deploy(web3, credentials, BigInteger.valueOf(27000000000L), BigInteger.valueOf(250000));
//            final RemoteCall<RandomBox> keySCode = RandomBox.deploy(web3, credentials, BigInteger.valueOf(27000000000L), BigInteger.valueOf(250000));

          /*  new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        keySCode.observable().flatMap(new Func1<RandomBox, Observable<?>>() {
                            @Override
                            public Observable<RandomBox> call(RandomBox randomBox) {
                                return Observable.just(randomBox);
                            }
                        }).subscribe(new Action1<Object>(){
                            @Override
                            public void call(Object o) {

                            }
                        });
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();*/

            // 调用转账方法
//            TransactionReceipt receipt = keySCode.transfer("0x672b1F95e0ad19d26c36EBf3BB0F11591879A998", BigInteger.valueOf(1)).send();
//            RemoteCall<String> remoteCall = keySCode.ceoAddress();

            // 打印交易Hash
            System.out.println("---");

//            Log.e("WZZ","------" + clientVersion);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    private void init(){
        int REQUEST_EXTERNAL_STORAGE = 1;
        String[] PERMISSIONS_STORAGE = {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
        };
        int permission = ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);



        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(
                    MainActivity.this,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }

    //初始化链接
    private void initConecation(){
        mFormAddress.setText(ownAddress);
        mToAddress.setText(toAddress);
        mSerchAddress.setText(toAddress);
        try {
            String url = "http://10.0.2.2:7545";
            web3 = Web3jFactory.build(new HttpService(url));
            //            Web3j web3 = Web3jFactory.build(new HttpService());
            Web3ClientVersion web3ClientVersion  = null;

                web3ClientVersion = web3.web3ClientVersion().sendAsync().get();
            String clientVersion = web3ClientVersion.getWeb3ClientVersion();
            textview.setText(clientVersion);


            //设置秘钥
            credentials = Credentials.create("c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3");
//        mSerchAddress
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.mBTestTrasation:
                    testTransation();
                break;
            case R.id.mBTestBlance:
                    testBlance();
                break;
        }
    }

    Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what){
                //部署合约
                case 0:
//                    mtvTestDeploy.setText("getContractAddress----" + kittyAccessControl.getContractAddress());
                    break;
                //查询余额
                case 1:
                    String sb = (String) msg.obj;
                    mSerachBlance.setText(sb);
                    break;
            }
            return false;
        }
    }
    );

    //部署合约
    public void mBtnTestDeploy(View view){
        credentials = Credentials.create("c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3");
//        RemoteCall<KittyAccessControl_sol_KittyAccessControl> keySCode = KittyAccessControl_sol_KittyAccessControl.deploy(web3, credentials, BigInteger.valueOf(27000000000L), BigInteger.valueOf(250000));
//        final RemoteCall<RandomBox> keySCode = RandomBox.deploy(web3, credentials, GAS_PRICE, GAS_LIMIT);
//        final RemoteCall<KittyAccessControl> keySCode = KittyAccessControl.deploy(web3, credentials, GAS_PRICE, GAS_LIMIT);
//
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    try {
//                        keySCode.observable().flatMap(new Func1<KittyAccessControl, Observable<?>>() {
//                            @Override
//                            public Observable<KittyAccessControl> call(KittyAccessControl randomBox) {
//                                return Observable.just(randomBox);
//                            }
//                        }).subscribe(new Action1<Object>(){
//                            @Override
//                            public void call(Object o) {
//                                kittyAccessControl = (KittyAccessControl)o;
//                                Message message  = Message.obtain();
//                                message.what = 0;
//                                mHandler.sendMessage(message);
//                                Log.e("Tag","ran" + randomBox.getContractAddress());
//                            }
//                        });
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                }
//            }).start();

    }

    //加载合约
    public void mBtnTestLoad(View view){
//        if (randomBox != null) {
//            String contractAddress  =  "0x8f0483125fcb9aaaefa9209d8e9d7b9c8b9fb90f";
            String kittyBaseAddress  =  "0x30753e4a8aad7f8597332e813735def5dd395028";
            String RandomBoxAddress  =  "0xecfcab0a285d3380e488a39b4bb21e777f8a4eac";
//            String contractAddress  =  kittyAccessControl.getContractAddress();
//        kittyBase = KittyBase.load(kittyBaseAddress,web3,credentials,GAS_PRICE,GAS_LIMIT);
        randomBox = RandomBox.load(RandomBoxAddress,web3,credentials,GAS_PRICE,GAS_LIMIT);
//            kittyAccessControl1 = KittyAccessControl.load(contractAddress,web3,credentials,GAS_PRICE,GAS_LIMIT);
//            Log.e("tag","-p--" + kittyAccessControl1.getContractAddress());
//            randomBox1.getContractAddress();
//        }else{
//            Toast.makeText(this,"调用合约地址不存在",Toast.LENGTH_SHORT).show();
//        }
    }

    //执行合约中的方法
     public void mBtnTestMethod(View view){
//         kittyAccessControl1.setCEO("100");
         BigInteger value = Convert.toWei("1.0", Convert.Unit.ETHER).toBigInteger();
         final RemoteCall<TransactionReceipt> rm =  randomBox.openBox(value);
//         randomBox.setDisableFalse();

//         final RemoteCall<TransactionReceipt> rm =  randomBox.setDisableFalse();
         new Thread(new Runnable() {
             @Override
             public void run() {
                 try {
                     rm.observable().flatMap(new Func1<TransactionReceipt, Observable<?>>() {
                         @Override
                         public Observable<TransactionReceipt> call(TransactionReceipt bigInteger) {
                             return Observable.just(bigInteger);
                         }
                     }).subscribe(new Action1<Object>(){
                         @Override
                         public void call(Object o) {
                             TransactionReceipt ss = (TransactionReceipt)o;
                             List<RandomBox.OpenBoxEventResponse> list  = randomBox.getOpenBoxEvents(ss);
                             Log.e("Tag","ran" + ss);
                         }
                     });
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
             }
         }).start();
     }

    //查询余额
    private void testBlance() {
        // //获取余额
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        EthGetBalance ethGetBalance1 = web3.ethGetBalance(toAddress, DefaultBlockParameterName.LATEST).send();
                        BigDecimal balance = new BigDecimal(ethGetBalance1.getBalance().divide(new BigInteger("10000000000000")).toString());
                        BigDecimal nbalance = balance.divide(new BigDecimal("100000"), 8, BigDecimal.ROUND_DOWN);
                        Message message = Message.obtain();
                        message.what = 1;
                        message.obj = nbalance + "eth";
                        mHandler.sendMessage(message);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
//            BigDecimal balance = new BigDecimal(ethGetBalance1.getBalance().divide(new BigInteger("10000000000000")).toString());
//            BigDecimal nbalance = balance.divide(new BigDecimal("100000"), 8, BigDecimal.ROUND_DOWN);
    }

    //执行合约中的方法
    public void mBtnTestMethod2(View view){

//         kittyAccessControl1.setCEO("100");
        final RemoteCall<Tuple2<BigInteger, BigInteger>> rm =  randomBox.getPropsCount(ownAddress);
//         final RemoteCall<TransactionReceipt> rm =  randomBox.setDisableFalse();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    rm.observable().flatMap(new Func1<Tuple2<BigInteger, BigInteger>, Observable<?>>() {
                        @Override
                        public Observable<Tuple2<BigInteger, BigInteger>> call(Tuple2<BigInteger, BigInteger> bigInteger) {
                            return Observable.just(bigInteger);
                        }
                    }).subscribe(new Action1<Object>(){
                        @Override
                        public void call(Object o) {
                            Tuple2<BigInteger, BigInteger> ss = (Tuple2<BigInteger, BigInteger>)o;
                            Log.e("Tag","ran" + ss);
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }


    //测试交易
    private void testTransation() {
        try {
                //转账人私钥

                //getNonce（这里的Nonce我也不是很明白，大概是交易的笔数吧）
                EthGetTransactionCount ethGetTransactionCount = null;

                ethGetTransactionCount = web3.ethGetTransactionCount(
                                     ownAddress, DefaultBlockParameterName.LATEST).sendAsync().get();

                BigInteger nonce = ethGetTransactionCount.getTransactionCount();


                //创建交易，这里是转0.5个以太币
                 BigInteger value = Convert.toWei("0.5", Convert.Unit.ETHER).toBigInteger();
                 RawTransaction rawTransaction = RawTransaction.createEtherTransaction(
                                 nonce, GAS_PRICE, GAS_LIMIT, toAddress, value);

               //签名Transaction，这里要对交易做签名
               byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
                String hexValue = Numeric.toHexString(signedMessage);

                //发送交易
                EthSendTransaction ethSendTransaction =
                                 web3.ethSendRawTransaction(hexValue).sendAsync().get();
                String transactionHash = ethSendTransaction.getTransactionHash();

                //获得到transactionHash后就可以到以太坊的网站上查询这笔交易的状态了
                 System.out.println(transactionHash);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
